﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UIObjects.TreeViewInterfaces;
#if SILVERLIGHT
using AbstraX.ClientInterfaces;
using AbstraX.TypeMappings;
using SL4PopupMenu;
using System.Windows.Controls;
#else
using AbstraX.ServerInterfaces;
#endif
using Entities = AbstraX.BindingsTreeEntities;
using System.Collections.ObjectModel;
using AbstraX.Contracts;
using MvvmTreeView;
using System.ServiceModel.DomainServices.Client;
using System.Windows;
using System.Diagnostics;

namespace AbstraX.ViewModels.BindingsTree
{
    public class BindingsTreeNodeElement : BindingsTreeNodeBase
    {
        private Entities.Element element;
        private ContextMenu contextMenu;

        public BindingsTreeNodeElement(IBindingsTreeService bindingsTreeService, ITreeView treeView, Entities.Element element) : base(bindingsTreeService, treeView)
        {
            this.element = element;
            this.Tag = element;
        }

#if SILVERLIGHT
        private void MenuCheckedChanged(object sender, MenuCheckedEventArgs args)
        {
            var popupMenu = (PopupMenu) args.Menu;
            var popupMenuItem = (PopupMenuItem) args.MenuItem;
            var checkBox = (CheckBox) args.Checkbox;
            var isChecked = args.IsChecked;
            var type = (string) popupMenuItem.Tag;

            if (args.CheckboxGroup == "ConstructType")
            {
                element.ConstructType = (ConstructType) Enum.Parse(typeof(ConstructType), (string) popupMenuItem.Tag, false);
            }
            else if (args.CheckboxGroup == "ContainerType")
            {
                element.ContainerType = (ContainerType)Enum.Parse(typeof(ContainerType), (string)popupMenuItem.Tag, false);
            }
            else
            {
                Debugger.Break();
            }

            var submitOperation = bindingsTreeService.Update(element);

            submitOperation.Completed += (sender2, e) =>
            {
                if (submitOperation.HasError)
                {
                    Debugger.Break();
                }
            };

            contextMenu = null;
        }

        private List<IContextMenuItem> GetConstructTypeMenus(ConstructType allowableTypes, ConstructType type)
        {
            var items = new List<IContextMenuItem>();

            foreach (var field in typeof(ConstructType).GetFields().Where(f => f.IsLiteral))
            {
                var constructType = (ConstructType) field.GetValue(typeof(ConstructType));

                if (constructType != ConstructType.NotSet)
                {
                    if ((constructType & allowableTypes) == constructType)
                    {
                        bool selected;

                        if (type == constructType)
                        {
                            selected = true;
                        }
                        else
                        {
                            selected = false;
                        }

                        items.Add(new CheckBoxContextMenuItem
                        {
                            Text = Enum.GetName(typeof(ConstructType), constructType),
                            IsChecked = selected,
                            CheckChanged = MenuCheckedChanged,
                            CheckBoxGroup = "ConstructType",
                            Tag = constructType.ToString()
                        });
                    }
                }
            }

            return items;
        }

        private List<IContextMenuItem> GetContainerTypeMenus(ContainerType allowableTypes, ContainerType type)
        {
            var items = new List<IContextMenuItem>();

            foreach (var field in typeof(ContainerType).GetFields().Where(f => f.IsLiteral))
            {
                var containerType = (ContainerType)field.GetValue(typeof(ContainerType));

                if (containerType != ContainerType.NotSet)
                {
                    if ((containerType & allowableTypes) == containerType)
                    {
                        bool selected;

                        if (type == containerType)
                        {
                            selected = true;
                        }
                        else
                        {
                            selected = false;
                        }

                        items.Add(new CheckBoxContextMenuItem
                        {
                            Text = Enum.GetName(typeof(ContainerType), containerType),
                            IsChecked = selected,
                            CheckChanged = MenuCheckedChanged,
                            CheckBoxGroup = "ContainerType",
                            Tag = containerType.ToString()
                        });
                    }
                }
            }

            return items;
        }

        public override ContextMenu ContextMenu
        {
            get
            {
                if (contextMenu == null)
                {
                    var allowableConstructTypes = element.AllowableConstructTypes;
                    var allowableContainerTypes = element.AllowableContainerTypes;
                    var constructType = element.ConstructType;
                    var containerType = element.ContainerType;

                    contextMenu = new ContextMenu
                    {
                        Items = new List<IContextMenuItem>()
                        {
                            new ContextMenuItem
                            {
                                Text = "Select Construct Type",
                                Items = GetConstructTypeMenus(allowableConstructTypes, constructType),
                                Tag = "ConstructType"
                            },
                            new ContextMenuItem
                            {
                                Text = "Select Container Type",
                                Items = GetContainerTypeMenus(allowableContainerTypes, containerType),
                                Tag = "ContainerType"
                            }
                        }
                    };
                }

                return contextMenu;
            }
        }
#endif

        public override void LoadChildren()
        {
            var element = (Entities.Element)this.Tag;

#if SILVERLIGHT
            var children = bindingsTreeService.LoadChildren<Entities.Element>(element);

            children.CollectionChanged += (s, e) =>
            {
                ChildrenLoaded(children);
            };

#endif
            treeView.SetBusy(this, true);
        }

        public override void OnSelect()
        {
        }

        public override string SelectionStatus
        {
            get
            {
                return element.DataType.FullyQualifiedName;
            }
        }

        public override Entity Entity
        {
            get
            {
#if SILVERLIGHT
                return element;
#else
                return null;
#endif
            }
        }

        protected override void ChildrenLoaded(IBindingsTreeCollection children)
        {
            isChildrenLoaded = true;

            this.RemoveSpinster();

            base.AddChildren(children);

            treeView.SetBusy(this, false);
        }

        public override string Text
        {
            get
            {
                return element.GetName();
            }

            set
            {
                throw new NotImplementedException();
            }
        }

        public override List<string> AddNewShortCuts
        {
            get { throw new NotImplementedException(); }
        }

        public override void AddNew(string shortCut)
        {
            throw new NotImplementedException();
        }

        public override void DragStarting(object sender, UIObjects.DragDropInterfaces.ItemDragEventArgs e)
        {
        }

        public override void DragCompleted(object sender, UIObjects.DragDropInterfaces.ItemDragEventArgs e)
        {
        }

        public override void ItemDropped(object sender, UIObjects.DragDropInterfaces.ItemDragEventArgs e, int insertionIndex)
        {
        }

        public override void GiveFeedback(object sender, UIObjects.DragDropInterfaces.GiveFeedbackEventArgs e)
        {
        }

        public override void DragEnter(object sender, UIObjects.DragDropInterfaces.DragEventArgs e)
        {
        }

        public override void DragLeave(object sender, UIObjects.DragDropInterfaces.DragEventArgs e)
        {
        }

        public override void DragOver(object sender, UIObjects.DragDropInterfaces.DragEventArgs e)
        {
        }

        public override float ChildOrdinal
        {
            get
            {
                return element.GetChildOrdinal();
            }
            set
            {
                throw new NotImplementedException();
            }
        }

        public override bool? HasChildren
        {
            get
            {
                return element.GetHasChildren();
            }
        }
    }
}
